#include "palins.h"
#include "parser.h"
#include "Crivo.h"

/*
 * Metodo que busca por palavras e frases palindromos
 */
void Palins::checkPalins(Parser &parser, int mode)
{
	vector<string> *words = parser.getWords();
	vector<string> *phrases = parser.getPhrases();

	extern int palindromeWTotal;
	extern int palindromePTotal;
	extern int primeTotal;

	extern Crivo *erathostenes;

	extern vector<string> *palins_words;
	extern vector<string> *palins_phrases;
	extern vector<string> *p_asciisum;
	extern vector<string> *w_asciisum;

	/* enquanto existirem palavras no vetor de palavras */
	while (!words->empty()) {
		string word = words->back();
		words->pop_back();

		/* inverte a palavra */
		string w_reverse = string(word.rbegin(), word.rend());

		/* se o inverso for igual a palavra original ela eh palindromo */
		if (word == w_reverse) {
			/* eh inserida no vetor de palavras palindromos */
			palins_words->push_back(word);
			palindromeWTotal++;
			/* e verificado se a soma ASCII eh um numero primo */
			if(erathostenes->testaPrimo(word)) {
				w_asciisum->push_back("PRIME");
				primeTotal++;
			}
			else
				w_asciisum->push_back("NOT PRIME");
		}
	}
	
	/* se o modo de execucao for WORDS_PHRASES eh realizado o mesmo procedimento para o vetor de frases */
	if(mode == WORDS_PHRASES){
		while(!phrases->empty()){
			string phrase = phrases->back();
			phrases->pop_back();
			
			if(phrase.length() > 1 && checkPalinsPhrase(phrase)) {
				palins_phrases->push_back(phrase);
				palindromePTotal++;
				if(erathostenes->testaPrimo(phrase)) {
					p_asciisum->push_back("PRIME");
					primeTotal++;
				}
				else
					p_asciisum->push_back("NOT PRIME");
			}
		}
	}
}

/*
 * Metodo para fazer a verificacao de frases palindromos
 */
bool Palins::checkPalinsPhrase(string str){
	string::iterator it;
	
	// funcao que limpa string recebida
	for(it = str.begin(); it != str.end(); it++)
	{
		if(*it==' ' || *it == '\n' || *it == ',' || *it == '.' || *it == '|' || *it== '!' || *it=='?' || *it==';' || *it == ':' || *it == 39 || *it =='(' || *it == ')' || *it == 44 || isalpha(*it)) {
			str.erase(it);
			it--;
		}
	}
	// transforma a string recebida em letras minusculas 
	str = toLower(str);
	
	string p_reverse = string(str.rbegin(), str.rend());
	
	if (str == p_reverse) 
		return true;
	else 
		return false;

}

/*
 * Metodo para converter uma string para lowercase
 */
string& Palins::toLower(string& str, locale loc)
{
	for(string::iterator it = str.begin(); it!=str.end(); ++it)
		*it = tolower(*it, loc);

	return str;
}
